package com.feinno.urcs.group.interop.service;

import com.feinno.database.DataRow;
import com.feinno.database.DataTable;
import com.feinno.database.Database;
import com.feinno.urcs.group.fxdb.FXPoolService;
import com.feinno.urcs.group.fxdb.PooledDatabaseLoader;
import com.feinno.urcs.group.interop.FxDataValidateGrpDao;
import com.feinno.urcs.group.interop.entity.DataValidateGroupBaseInfo;
import com.feinno.urcs.group.interop.entity.DataValidateGroupMemberInfo;
import com.feinno.urcs.types.MobileNo;
import com.feinno.util.StringUtils;
import com.google.gson.Gson;
import org.helium.framework.annotations.FieldSetter;
import org.helium.framework.annotations.ServiceImplementation;
import org.helium.framework.annotations.ServiceSetter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Li.Hongbo <lihongbo@feinno.com>
 */
@ServiceImplementation
public class FxDataValidateGrpDaoImpl implements FxDataValidateGrpDao {
	private static final Logger LOGGER = LoggerFactory.getLogger(FxDataValidateGrpDaoImpl.class);

	@FieldSetter("${GGRPDB}")
	private Database ggrpDb;

	@FieldSetter(value = "${GRPDB_POOLS_XML}", loader = PooledDatabaseLoader.class)
	private Map<Integer, Database> dbs;

	@ServiceSetter
	private FXPoolService poolService;


	/**
	 * 获取指定PhysicalPool的GRPDB
	 *
	 * @return 返回Database连接
	 * @throws SQLException
	 */
	private Database getDatabase(DataValidateGroupBaseInfo info) throws Exception {

		if (info != null) {
			int logicPool = 0;
			if (info.getGroupLogicalPool() > 0) {
				logicPool = info.getGroupLogicalPool();
			} else {
				String sql = "SELECT LogicPool FROM GGRP_SearchGroup WHERE GroupId = ?";
				DataTable dt = ggrpDb.executeTable(sql, info.getGroupId());
				logicPool = dt.getRow(0).getInt("LogicPool");

			}
			int poolid = poolService.getPhyicalPool(logicPool);
			return dbs.get(poolid);
		}
		return null;

	}


	public int upDomainConversationIds(String groupDomain, DataValidateGroupBaseInfo groupIndex) throws SQLException {
		String sql = "update GRP_Group set ConversationId=? ,Domain = ? ,Creator= ? where GroupId =? ";
		try {
			int ret = getDatabase(groupIndex).executeNonQuery(sql, groupIndex.getConversationId(), groupDomain.trim(), groupIndex.getCreateMobileNo(), groupIndex.getGroupId());
			return ret;

		} catch (Exception e) {
			LOGGER.error(String.format("upDomainConversationIds error groupDaoMain=%s,groupId=%s ,conversationId=%s,Creator= ?", groupDomain, groupIndex.getGroupId(), groupIndex.getConversationId(), groupIndex.getCreateMobileNo()), e);

		}
		return 0;
	}

	public DataValidateGroupMemberInfo getGroupSuperAdmin(DataValidateGroupBaseInfo gindex) throws Exception {
		DataValidateGroupMemberInfo info = getGroupSuperAdminIdentity(gindex);
		if (info == null) info = getGroupSuperAdminTime(gindex);
		return info;

	}

	private DataValidateGroupMemberInfo getGroupSuperAdminTime(DataValidateGroupBaseInfo gindex) throws Exception {
		String sql = "select UserId,MemberLogicalPool,MobileNo,ReferByMobileNo,Identity from GRP_GroupMember where GroupId=? and Identity<4 order by AddGroupTime ";
		DataValidateGroupMemberInfo result = null;
		try {
			DataTable dt = getDatabase(gindex).executeTable(sql, gindex.getGroupId());

			if (dt != null && dt.getRows().size() > 0) {
				DataRow dr = dt.getRow(0);
				result = new DataValidateGroupMemberInfo(
						gindex.getGroupId(),
						dr.getInt("UserId"),
						dr.getInt("MemberLogicalPool"),
						dr.getString("MobileNo"),
						dr.getString("ReferByMobileNo"), dr.getInt("Identity")
				);
			}
		} catch (Exception e) {
			LOGGER.error(String.format("getGroupSuperAdmin args=%s", new Gson().toJson(gindex)), e);
		}
		return result;

	}

	private DataValidateGroupMemberInfo getGroupSuperAdminIdentity(DataValidateGroupBaseInfo gindex) throws Exception {
		String sql = "select UserId,MemberLogicalPool,MobileNo,ReferByMobileNo,Identity from GRP_GroupMember where GroupId=? and Identity=1 ";
		DataValidateGroupMemberInfo result = null;
		try {
			DataTable dt = getDatabase(gindex).executeTable(sql, gindex.getGroupId());

			if (dt != null && dt.getRows().size() > 0) {
				DataRow dr = dt.getRow(0);
				result = new DataValidateGroupMemberInfo(
						gindex.getGroupId(),
						dr.getInt("UserId"),
						dr.getInt("MemberLogicalPool"),
						dr.getString("MobileNo"),
						dr.getString("ReferByMobileNo"),
						dr.getInt("Identity")
				);
			}
		} catch (Exception e) {
			LOGGER.error(String.format("getGroupSuperAdmin args=%s", new Gson().toJson(gindex)), e);

		}
		return result;

	}

	public List<DataValidateGroupMemberInfo> getGroupMembers(DataValidateGroupBaseInfo gindex) throws SQLException {
		String sql = "select UserId,MemberLogicalPool,MobileNo,ReferByMobileNo,Identity from GRP_GroupMember where GroupId=?";
		List<DataValidateGroupMemberInfo> result = new ArrayList<DataValidateGroupMemberInfo>();
		try {
			DataTable dt = getDatabase(gindex).executeTable(sql, gindex.getGroupId());

			if (dt != null) {
				for (DataRow resultSet : dt.getRows()) {
					//String mobileNo, String referByMobileNo, int userId, int userLogicPool, int groupId
					String referBy = resultSet.getString("ReferByMobileNo");
					DataValidateGroupMemberInfo info = new DataValidateGroupMemberInfo(
							gindex.getGroupId(),
							resultSet.getInt("UserId"),
							resultSet.getInt("MemberLogicalPool"),
							resultSet.getString("MobileNo"),
							StringUtils.isNullOrEmpty(referBy) ? gindex.getSuperAdminMobile() : referBy,
							resultSet.getInt("Identity")
					);
					result.add(info);
				}
			}
		} catch (Exception e) {
			LOGGER.error(String.format("getGroupMembers args=%s", new Gson().toJson(gindex)), e);

		}
		return result;

	}

	public int updateGroupMemberIdentity(DataValidateGroupBaseInfo index, MobileNo mobileNo, int identity) throws Exception {
		String sql = "UPDATE GRP_GroupMember SET Identity = ? WHERE GroupId =? AND MobileNo = ?;";
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int ec = getDatabase(index).executeNonQuery(sql, identity, index.getGroupId(), mobileNo.toString());
			// update fetion MemberlistMinorVersion
			if (ec > 0) {
				String sqlVersion = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion+1 WHERE  GroupId = ?";
				getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
			}
			return ec;
		} catch (SQLException e) {
			LOGGER.error(String.format("updateGroupMemberRole Error index=%s member=%s  identity=%s  ", index, mobileNo, identity), e);
			throw e;
		}
	}

	public int updateGroupMemberIdentityWithUserId(DataValidateGroupBaseInfo index, int userId, int identity) throws Exception {
		String sql = "UPDATE GRP_GroupMember SET Identity = ? WHERE GroupId =? AND UserId = ?;";
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int ec = getDatabase(index).executeNonQuery(sql, identity, index.getGroupId(), userId);
			// update fetion MemberlistMinorVersion
			if (ec > 0) {
				String sqlVersion = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion+1 WHERE  GroupId = ?";
				getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
			}
			return ec;
		} catch (SQLException e) {
			LOGGER.error(String.format("updateGroupMemberRole Error index=%s userId=%s  identity=%s  ", index, userId, identity), e);
			throw e;
		}
	}

	public void upGroupMembers(DataValidateGroupBaseInfo gindex, List<DataValidateGroupMemberInfo> members) throws Exception {
		String sql = "update GRP_GroupMember set MobileNo=? ,ReferByMobileNo=? where GroupId=? and UserId=?";
		try {
			for (DataValidateGroupMemberInfo member : members) {
				int ret = getDatabase(gindex).executeNonQuery(sql, member.getMobileNo().toString(), member.getReferByMobileNo().toString(), member.getGroupId(), member.getUserId());
				LOGGER.info(String.format("upGroupMembers ret=%s member=%s", ret, new Gson().toJson(members)));
			}

		} catch (Exception e) {
			LOGGER.error(String.format("upGroupMembers args=%s", new Gson().toJson(members)), e);

		}

	}

	@Override
	public void getCreator(DataValidateGroupBaseInfo fxGroupIndex) throws Exception {
		String sql = "select GroupId,Creator from GRP_Group where GroupId=? ";
		DataValidateGroupMemberInfo result = null;
		try {
			DataTable dt = getDatabase(fxGroupIndex).executeTable(sql, fxGroupIndex.getGroupId());

			if (dt != null && dt.getRows().size() > 0) {
				DataRow dr = dt.getRow(0);
				fxGroupIndex.setCreateMobileNo(dr.getString("Creator"));
			}
		} catch (Exception e) {
			LOGGER.error(String.format("getCreator args=%s", new Gson().toJson(fxGroupIndex)), e);

		}
	}
}
